using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using Deepcode.Flux.Core.Data;

namespace Deepcode.Flux.Core.Systems.Workflow.Bases
{
	/// <summary>
	/// Manager class for the workflow processes within a definition
	/// </summary>
	public class Processes : BaseManager
	{
		#region Constructors
		public Processes() : base() { }
		public Processes(SqlConnection CurrentConnection) : base(CurrentConnection) { }
		public Processes(SqlConnection CurrentConnection, SqlTransaction CurrentTransaction) : base(CurrentConnection, CurrentTransaction) { }
		#endregion
		#region Data Retrieval
		/// <summary>
		/// Get all processes for a particular definition - ordered by rank
		/// </summary>
		/// <param name="DefinitionID"></param>
		/// <returns></returns>
		public Process[] GetProcessByDefinitionID(int DefinitionID)
		{
			DataTable results = new DataTable();

			EstablishConnection();
			SqlDataAdapter da = this.CreateDataAdapter("coreWFProcessGetByDefinitionID");
			da.SelectCommand.Parameters.Add(SQLUtility.ParameterIn("@id", SqlDbType.Int, 4, DefinitionID));
			da.Fill(results);
			ReleaseConnection();

			List<Process> list = new List<Process>();
			foreach (DataRow r in results.Rows)
				list.Add(new Process(r));

			return list.ToArray();
		}
		/// <summary>
		/// Get the lowest rank process for a definition ID
		/// </summary>
		/// <param name="DefinitionID"></param>
		/// <returns></returns>
		public Process GetStartProcessForDefinitionID(int DefinitionID)
		{
			Process [] list = GetProcessByDefinitionID( DefinitionID );
			if( list.Length > 0 ) return list[0];
			return null;
		}
		/// <summary>
		/// Get a process by its ID
		/// </summary>
		/// <param name="ID"></param>
		/// <returns></returns>
		public Process GetProcessByID(int ID)
		{
			DataTable result = new DataTable();

			EstablishConnection();
			SqlDataAdapter da = this.CreateDataAdapter("coreWFProcessGetByID");
			da.SelectCommand.Parameters.Add(SQLUtility.ParameterIn("@id", SqlDbType.Int, 4, ID));
			da.Fill(result);
			ReleaseConnection();

			if (result == null) return null;
			if (result.Rows.Count < 1) return null;

			return new Process(result.Rows[0]);
		}
		#endregion
		#region Save Record
		/// <summary>
		/// Saves the specified process to the database
		/// </summary>
		/// <param name="process"></param>
		/// <returns></returns>
		public int Save(Process process)
		{
			EstablishConnection();
			SqlCommand cmd = this.CreateSqlCommand("coreWFProcessSave");
			SqlParameter result = SQLUtility.ParameterInOut("@id", SqlDbType.Int, 4, process.PK_ID);
			cmd.Parameters.Add(result);

			cmd.Parameters.Add( SQLUtility.ParameterIn("@FK_DefinitionID", SqlDbType.Int, 4, process.FK_DefinitionID) );
			cmd.Parameters.Add( SQLUtility.ParameterIn("@ProcessName", SqlDbType.NVarChar, 500, process.ProcessName));
			cmd.Parameters.Add( SQLUtility.ParameterIn("@ProcessType", SqlDbType.Int, 4, (int) process.ProcessType));
			cmd.Parameters.Add( SQLUtility.ParameterIn("@DataCanView", SqlDbType.Bit, 1, process.DataCanView ));
			cmd.Parameters.Add( SQLUtility.ParameterIn("@DataCanEdit", SqlDbType.Bit, 1, process.DataCanEdit ));
			cmd.Parameters.Add( SQLUtility.ParameterIn("@Rank", SqlDbType.Int, 4, process.Rank ));

			cmd.ExecuteNonQuery();
			ReleaseConnection();

			if( process.PK_ID == -1 ) 
				process.PK_ID = (int) result.Value; 

			return process.PK_ID;
		}
		#endregion
		#region Delete Records
		/// <summary>
		/// Deletes the specified process from the database and 
		/// cascades into deleting taskings and process start actions
		/// </summary>
		/// <param name="ID"></param>
		/// <returns></returns>
		public bool DeleteByID(int ID)
		{
			EstablishConnection();
			SqlCommand cmd = this.CreateSqlCommand("coreWFProcessDeleteByID");
			cmd.Parameters.Add(SQLUtility.ParameterIn("@id", SqlDbType.Int, 4, ID));
			cmd.ExecuteNonQuery();
			ReleaseConnection();
			return true;
		}
		#endregion
	}
}
